package JitUtils;

import Index.Index;
import Index.TreeNode;
import gitobject.Tree;
import repository.Repository;
import sha1.SHA1;

import java.io.*;
import java.nio.Buffer;
import java.nio.charset.StandardCharsets;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.*;

/**
 * @author shkstart
 * @create 2021-11-15 22:37
 */
public class FileHash {
    public static TreeNode fileHash(File file, String mark) throws IOException {  //计算文件hash
        Index index = new Index();
        TreeNode temp = new TreeNode();
        temp.setType("blob");
        temp.setBase("blob");
        temp.setpath(file.getAbsolutePath());
        temp.setChildren(null);
        MessageDigest messageDigest = null;
        FileInputStream is = null;
        try {           //根据文件内容计算文件hash键值
            is = new FileInputStream(file);
            byte[] buffer = new byte[1024];
            messageDigest = MessageDigest.getInstance("SHA-1");
            int len = 0;
            while ((len = is.read(buffer)) != -1) {
                messageDigest.update(buffer, 0, len);
            }
            byte[] hashCode = messageDigest.digest();
            String result = "";
            for (int i = 0; i < hashCode.length; i++) {
                if ((int)(hashCode[i] & 0xFF) < 16) { // avoiding the lack of '0'
                    result += '0';
                }
                result += Integer.toString(hashCode[i] & 0xFF, 16);
            }
            temp.setId(result);
            String blobItem = "100644  " + result + "  0  " + file.getAbsolutePath();
            if(!index.getBlobList().contains(blobItem) && mark.equals("1")) {
                ArrayList< String> bloblist = index.getBlobList();
                bloblist.add(blobItem);         //添加进暂存区的bloblist列表
                index.setBlobList(bloblist);;   //更新暂存区到本地
                index.writeObject();
            }
            return temp;

        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            try {
                if (is != null)
                    is.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }

        return null;
    }

    public static TreeNode hashOfDic(File dir) throws Exception { //深度优先遍历计算出文件夹的hash值字符串
        TreeNode dic = new TreeNode();
        dic.setType("tree");
        dic.setBase("tree");
        dic.setpath(dir.getAbsolutePath());
        String treeValue = "";
        List<String> hashcode = new ArrayList<>();
        File[] fs = dir.listFiles();
        if(fs != null) {
            Arrays.sort(fs, new Comparator<File>() {
                @Override
                public int compare(File o1, File o2) {
                    return (o1.getAbsolutePath().compareTo(o2.getAbsolutePath()));
                }
            });

            for (int i = 0; i < fs.length; i++) {
                if(fs[i] == null){
                    return null;
                }
                if (fs[i].isFile()) {
                    TreeNode fileNode = fileHash(fs[i],"1");
                    String strOfFile = "100644 blob " + fileNode.getId() + " " + fs[i].getName();
                    dic.addChildren(fileNode);
                    hashcode.add(strOfFile);
                }
                if (fs[i].isDirectory()) {
                    TreeNode temp = hashOfDic(fs[i]);
                    String hashOfDic = temp.getId();
                    String treeId = "040000 tree " + hashOfDic + " " + fs[i].getName();
                    hashcode.add(treeId);
                    dic.addChildren(temp);
                }
            }
        }
        for (int j = 0; j < hashcode.size(); j++) {
            String temp = hashcode.get(j);
            if(treeValue == "")
                treeValue += temp + "\n";
            else
                treeValue += temp;
        }
        MessageDigest messageDigest = null;
        messageDigest = MessageDigest.getInstance("SHA-1");
        messageDigest.update(treeValue.getBytes(StandardCharsets.UTF_8));
        byte[] hashCode = messageDigest.digest();
        String tree = "";
        for (int i = 0; i < hashCode.length; i++) {
            if ((int)(hashCode[i] & 0xFF) < 16) { // avoiding the lack of '0'
                tree += '0';
            }
            tree += Integer.toString(hashCode[i] & 0xFF, 16);
        }
        dic.setId(tree);
        hashcode.clear();
        return dic;

    }

}


